package com.demo.wormhole.autoconfiguration.rabbit;

import com.demo.wormhole.component.rabbit.annotation.RabbitListenerAnnotationBeanPostProcessor;
import com.demo.wormhole.component.rabbit.annotation.WormholeRabbitListenerAnnotationBeanPostProcessor;
import com.demo.wormhole.component.rabbit.factory.WormholeSimpleRabbitListenerContainerFactory;
import com.demo.wormhole.component.rabbit.template.ShadowRabbitTemplate;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.config.RabbitListenerConfigUtils;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.support.converter.SimpleMessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Role;

@ConditionalOnClass({RabbitTemplate.class, CachingConnectionFactory.class})
@ConditionalOnProperty("spring.rabbitmq.host")
@Configuration
public class WormholeRabbitAutoConfiguration {
    
    @Value("${spring.rabbitmq.listener.simple.acknowledge-mode}")
    private AcknowledgeMode acknowledgeMode;
    
    @Bean
    @Primary
    public RabbitTemplate rabbitTemplate(CachingConnectionFactory factory) {
        ShadowRabbitTemplate rabbitTemplate = new ShadowRabbitTemplate(factory);
        return rabbitTemplate;
    }
    
    @ConditionalOnClass
    @Bean(name = RabbitListenerConfigUtils.RABBIT_LISTENER_ANNOTATION_PROCESSOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public RabbitListenerAnnotationBeanPostProcessor rabbitListenerAnnotationProcessor() {
        return new WormholeRabbitListenerAnnotationBeanPostProcessor();
    }
    
    @ConditionalOnClass(WormholeSimpleRabbitListenerContainerFactory.class)
    @Bean(name = "rabbitListenerContainerFactory")
    public RabbitListenerContainerFactory defaultRabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
        WormholeSimpleRabbitListenerContainerFactory rabbitListenerContainerFactory = new WormholeSimpleRabbitListenerContainerFactory();
        rabbitListenerContainerFactory.setConnectionFactory(connectionFactory);
        rabbitListenerContainerFactory.setConnectionFactory(connectionFactory);
        rabbitListenerContainerFactory.setMessageConverter(new SimpleMessageConverter());
        rabbitListenerContainerFactory.setAcknowledgeMode(acknowledgeMode);
        return rabbitListenerContainerFactory;
    }
}
